home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / PushbackInputStream.java < prev    next >
Text File  |  1998-09-22  |  8KB  |  223 lines

  1. /*
  2.  * @(#)PushbackInputStream.java    1.17 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.io;
  16.  
  17. /**
  18.  * This class is an input stream filter that provides a buffer into which data
  19.  * can be "unread."  An application may unread data at any time by pushing it
  20.  * back into the buffer, as long as the buffer has sufficient room.  Subsequent
  21.  * reads will read all of the pushed-back data in the buffer before reading
  22.  * from the underlying input stream.
  23.  *
  24.  * <p>
  25.  * This functionality is useful when a fragment of code should read 
  26.  * an indefinite number of data bytes that are delimited by 
  27.  * particular byte values. After reading the terminating byte the
  28.  * code fragment can push it back, so that the next read 
  29.  * operation on the input stream will re-read that byte.
  30.  *
  31.  * @author  David Connelly
  32.  * @author  Jonathan Payne
  33.  * @version 1.17, 07/01/98
  34.  * @since   JDK1.0
  35.  */
  36. public
  37. class PushbackInputStream extends FilterInputStream {
  38.     /**
  39.      * The pushback buffer.
  40.      * @since   JDK1.1
  41.      */
  42.     protected byte[] buf;
  43.  
  44.     /**
  45.      * The position within the pushback buffer from which the next byte will
  46.      * be read.  When the buffer is empty, <code>pos</code> is equal to
  47.      * <code>buf.length</code>; when the buffer is full, <code>pos</code> is
  48.      * equal to zero.
  49.      *
  50.      * @since   JDK1.1
  51.      */
  52.     protected int pos;
  53.  
  54.     /**
  55.      * Creates a new pushback input stream with a pushback buffer
  56.      * of the specified size.
  57.      *
  58.      * @param  in    the input stream from which bytes will be read.
  59.      * @param  size  the size of the pushback buffer.
  60.      * @since  JDK1.1
  61.      */
  62.     public PushbackInputStream(InputStream in, int size) {
  63.     super(in);
  64.     this.buf = new byte[size];
  65.     this.pos = size;
  66.     }
  67.  
  68.     /**
  69.      * Creates a new pushback input stream with a one-byte pushback buffer.
  70.      *
  71.      * @param   in   the input stream from which bytes will be read.
  72.      */
  73.     public PushbackInputStream(InputStream in) {
  74.     this(in, 1);
  75.     }
  76.  
  77.     /**
  78.      * Reads the next byte of data from this input stream. The value 
  79.      * byte is returned as an <code>int</code> in the range 
  80.      * <code>0</code> to <code>255</code>. If no byte is available 
  81.      * because the end of the stream has been reached, the value 
  82.      * <code>-1</code> is returned. This method blocks until input data 
  83.      * is available, the end of the stream is detected, or an exception 
  84.      * is thrown. 
  85.      *
  86.      * <p> This method returns the most recently pushed-back byte, if there is
  87.      * one, and otherwise calls the <code>read</code> method of its underlying
  88.      * input stream and returns whatever value that method returns.
  89.      *
  90.      * @return     the next byte of data, or <code>-1</code> if the end of the
  91.      *             stream has been reached.
  92.      * @exception  IOException  if an I/O error occurs.
  93.      * @see        java.io.InputStream#read()
  94.      */
  95.     public int read() throws IOException {
  96.     if (pos < buf.length) {
  97.         return buf[pos++] & 0xff;
  98.     }
  99.     return super.read();
  100.     }
  101.  
  102.     /**
  103.      * Reads up to <code>len</code> bytes of data from this input stream into
  104.      * an array of bytes.  This method first reads any pushed-back bytes; after
  105.      * that, if fewer than than <code>len</code> bytes have been read then it
  106.      * reads from the underlying input stream.  This method blocks until at
  107.      * least 1 byte of input is available.
  108.      *
  109.      * @param      b     the buffer into which the data is read.
  110.      * @param      off   the start offset of the data.
  111.      * @param      len   the maximum number of bytes read.
  112.      * @return     the total number of bytes read into the buffer, or
  113.      *             <code>-1</code> if there is no more data because the end of
  114.      *             the stream has been reached.
  115.      * @exception  IOException  if an I/O error occurs.
  116.      */
  117.     public int read(byte[] b, int off, int len) throws IOException {
  118.     if (len <= 0) {
  119.         return 0;
  120.     }
  121.     int avail = buf.length - pos;
  122.     if (avail > 0) {
  123.         if (len < avail) {
  124.         avail = len;
  125.         }
  126.         System.arraycopy(buf, pos, b, off, avail);
  127.         pos += avail;
  128.         off += avail;
  129.         len -= avail;
  130.     }
  131.     if (len > 0) {
  132.         len = super.read(b, off, len);
  133.         if (len == -1) {
  134.         return avail == 0 ? -1 : avail;
  135.         }
  136.         return avail + len;
  137.     }
  138.     return avail;
  139.     }
  140.  
  141.     /**
  142.      * Pushes back a byte by copying it to the front of the pushback buffer.
  143.      * After this method returns, the next byte to be read will have the value
  144.      * <code>(byte)b</code>.
  145.      *
  146.      * @param      b   the <code>int</code> value whose low-order 
  147.      *             byte is to be pushed back.
  148.      * @exception IOException If there is not enough room in the pushback
  149.      *                  buffer for the byte.
  150.      */
  151.     public void unread(int b) throws IOException {
  152.     if (pos == 0) {
  153.         throw new IOException("Push back buffer is full");
  154.     }
  155.     buf[--pos] = (byte)b;
  156.     }
  157.  
  158.     /**
  159.      * Pushes back a portion of an array of bytes by copying it to the front
  160.      * of the pushback buffer.  After this method returns, the next byte to be
  161.      * read will have the value <code>b[off]</code>, the byte after that will
  162.      * have the value <code>b[off+1]</code>, and so forth.
  163.      *
  164.      * @param b the byte array to push back.
  165.      * @param off the start offset of the data.
  166.      * @param len the number of bytes to push back.
  167.      * @exception IOException If there is not enough room in the pushback
  168.      *                  buffer for the specified number of bytes.
  169.      * @since     JDK1.1
  170.      */
  171.     public void unread(byte[] b, int off, int len) throws IOException {
  172.     if (len > pos) {
  173.         throw new IOException("Push back buffer is full");
  174.     }
  175.     pos -= len;
  176.     System.arraycopy(b, off, buf, pos, len);
  177.     }
  178.  
  179.     /**
  180.      * Pushes back an array of bytes by copying it to the front of the
  181.      * pushback buffer.  After this method returns, the next byte to be read
  182.      * will have the value <code>b[0]</code>, the byte after that will have the
  183.      * value <code>b[1]</code>, and so forth.
  184.      *
  185.      * @param b the byte array to push back
  186.      * @exception IOException If there is not enough room in the pushback
  187.      *                  buffer for the specified number of bytes.
  188.      * @since     JDK1.1
  189.      */
  190.     public void unread(byte[] b) throws IOException {
  191.     unread(b, 0, b.length);
  192.     }
  193.  
  194.     /**
  195.      * Returns the number of bytes that can be read from this input stream
  196.      * without blocking.  This method calls the <code>available</code> method
  197.      * of the underlying input stream; it returns that value plus the number of
  198.      * bytes that have been pushed back.
  199.      *
  200.      * @return     the number of bytes that can be read from the input stream
  201.      *             without blocking.
  202.      * @exception  IOException  if an I/O error occurs.
  203.      * @see        java.io.FilterInputStream#in
  204.      */
  205.     public int available() throws IOException {
  206.     return pos + super.available();
  207.     }
  208.  
  209.     /**
  210.      * Tests if this input stream supports the <code>mark</code> and
  211.      * <code>reset</code> methods, which it does not.
  212.      *
  213.      * @return   <code>false</code>, since this class does not support the
  214.      *           <code>mark</code> and <code>reset</code> methods.
  215.      * @see     java.io.InputStream#mark(int)
  216.      * @see     java.io.InputStream#reset()
  217.      */
  218.     public boolean markSupported() {
  219.     return false;
  220.     }
  221.  
  222. }
  223.